// const p1 = new Promise((resolve,reject)=>{
//     console.log(p1)
//   // setTimeout(()=>{
//     resolve('1111')
//   // },10000)
// }).then(res=>{
//   console.log(p1)
//   // return '22222'
// })
// console.dir(p1)

// const p1 = new Promise((resolve,reject)=>{
//   console.log('1111')
//   const p2 = new Promise((resolve,reject)=>{
//     console.log('444444')
//     setTimeout(()=>{
//       resolve('2222')
//     },0)
//   })
//   resolve('33333')
//   p2.then(res=>{
//     console.log(res)
//   })
// }).then(res=>{
//   console.dir(res)
// })
// console.dir('999999')

/**
 * 阻止promise执行
 */
// let promise = new Promise((resolve, reject) => {
//   setTimeout(() => {
//     resolve(123);
//   }, 1000);
// })
// function wrap(p) {
//   let resol = null;
//   let abort = null;

//   let p1 = new Promise((resolve, reject) => {
//     resol = resolve;
//     abort = reject;
//   });

//   p1.abort = abort;
//   p.then(resol, abort);

//   return p1;
// }

// let newPromise = wrap(promise);

// newPromise.then(res => console.log(res))
// newPromise.abort()

/**
 * 顺序输出
 */


 var makePromise = function(value, time) {
  return new Promise(function(resolve, reject){
    setTimeout(function() {
      // console.log('value== ',value)
      resolve(value);
    }, time)
  })
};

function order(promises) {
  promises.reduce((pre,cur)=>{
    return pre.then((res)=>{
      console.log(res)
      // debugger
      return cur.then()
    })
  },Promise.resolve())
}

order([
  makePromise('a', 3000),
  makePromise('b', 2000),
  makePromise('c', 1000),
])



const createPromise = (id,time)=>()=>
  new Promise(resolve=>{
    setTimeout(()=>{
      console.log(`promise->${id}:${new Date()}`)
      resolve(id)
    },time)
  })

const tasks = [createPromise(4,3000),createPromise(2,2000),createPromise(0,1000)]
const doTask = tasks.reduce((pre,next)=>pre.then((res)=>{
  console.log(res)
  return next()
}),Promise.resolve())
doTask.then(()=>{console.log('all done')})


const p1 = new Promise(resolve=>{
  setTimeout(()=>{
    resolve(3333)
    console.log('timer1')
  },0)
  resolve(111)
  resolve(2222)
}).then(res=>{
  console.log(res)
  setTimeout(()=>{
    console.log('p1',p1)
  },0)
}).finally(res=>{
  console.log('finally',res)
})


/**
 * 
 * 大厂面试题promise
 */

// 使用promise实现每隔1秒打印1,2，3
const arr = [1,2,3]
arr.reduce((pre,cur)=>{
  return pre.then((res)=>{
    // if (res) {
    //   console.log(res)
    // }
    return new Promise(resolve=>{
      setTimeout(()=>{
        // resolve(console.log(cur))
        console.log(cur)
        resolve(cur)
      },1000)
    })
  })
},Promise.resolve())

// 使用promise是实现红绿灯交替重复亮  红灯3秒  黄灯2秒  绿灯1秒

function red(){
  console.log('red')
}
function yellow(){
  console.log('yellow')
}
function green(){
  console.log('green')
}
function createCB (timer,cb) {
  return new Promise(resolve=>{
    setTimeout(()=>{
      cb()
      resolve()
    },1000*timer)
  })
}
function step(){
  Promise.
  resolve()
  .then(()=>{
    return createCB(3,red)
  })
  .then(()=>{
    return createCB(2,yellow)
  })
  .then(()=>{
    return createCB(1,green)
  })
  .then(()=>{
    return step()
  })
}
step()


// 使用mergePromise，把传进去的数组promise按顺序先后执行  数据放到数组中返回
const time = (timer)=>{
  return new Promise(resolve=>{
    setTimeout(()=>{
      resolve()
    },timer)
  })
}
const ajax1=()=>time(2000).then(()=>{
  console.log(1)
  return 1
})

const ajax2=()=>time(1000).then(()=>{
  console.log(2)
  return 2
})
const ajax3=()=>time(1000).then(()=>{
  console.log(3)
  return 3
})

// 自己写的方法
// function mergePromise(promiseList){
//   return new Promise(resolve=>{
//     let data = []
//     promiseList.reduce(async(pre,cur)=>{
//       const res = await pre.then(()=>{
//         return cur()
//       })
//       data.push(res)
//       if (data.length===3){
//         resolve(data)
//       }
//     },Promise.resolve())
//   })
// }
//文档里的方法
function mergePromise(promiseList){
  const data = []
  let promise = Promise.resolve()
  promiseList.forEach(ajax=>{
    promise = promise.then(ajax).then(res=>{
      data.push(res)
      return data
    })
  })
  return promise
}
mergePromise([ajax1,ajax2,ajax3]).then(data=>{
  console.log('done')
  console.log(data)
})

// 1
// 2
// 3
// 'done'
// [1,2,3]

/**
 *  加载数组图片 同时加载一点数量的图片 
 *  先采用.race  最后用.all
 * 
 */
function limitLoad(urls,handler,limit) {
  const sequence = [...urls]
  let promises = sequence.splice(0,limit).map((url,index)=>{
    handler(url).then(()=>{
      return index
    })
  })
  return sequence.reduce((pCollect,url,currentIndex)=>{
    return pCollect.then(()=>{
      return Promise.race(promises)
    })
    .then(fastestIndex=>{
      promises[fastestIndex] = handler(url).then(()=>{
        return fastestIndex
      })
    })
    .catch(err=>{
      console.log(err)
    })
  },Promise.resolve())
  .then(()=>{
    return Promise.all(promises)
  })
}

function loadImg(url){
  return new Promise((resolve,reject)=>{
    const img = new Image()
    img.onload = function(){
      console.log('一张图片加载完成ulr==  ',url)
      resolve()
    }
    img.onerror=function(){
      reject('加载图片失败')
    }
    img.src = url
  })
}
const urls = [
  'https://img0.baidu.com/it/u=1077360284,2857506492&fm=26&fmt=auto',
  'https://img2.baidu.com/it/u=3864578316,873279422&fm=26&fmt=auto',
  'https://img1.baidu.com/it/u=2713203451,2755497443&fm=26&fmt=auto',
  'https://img2.baidu.com/it/u=1314911232,3565826320&fm=26&fmt=auto',
  'https://img0.baidu.com/it/u=3928903079,1184629296&fm=26&fmt=auto',
  'https://img0.baidu.com/it/u=2783242076,3911860021&fm=26&fmt=auto',
  'https://img0.baidu.com/it/u=3046839824,2843167936&fm=26&fmt=auto',
  'https://img1.baidu.com/it/u=1801510667,176844939&fm=26&fmt=auto',
  'https://img0.baidu.com/it/u=2237039644,3735368368&fm=26&fmt=auto',
  'https://img1.baidu.com/it/u=3517333914,639949515&fm=26&fmt=auto',
  'https://img0.baidu.com/it/u=2064236049,533493186&fm=26&fmt=auto',
]
limitLoad(urls,loadImg, 3)
.then(res=>{
  console.log('图片全部加载完成')
  console.log(res) 
})
.catch(e=>{
  console.log('图片加载出现问题')
  console.error(e)
})


// 再次调用then方法立即执行
const promise = new Promise((resolve,reject)=>{
  setTimeout(()=>{
    console.log('1111111111111')
    resolve('222222222222')
  },2000)
})
const start = new Date()
promise.then((res)=>{
  console.log(res, Date.now()-start)
})
promise.then((res)=>{
  console.log(res, Date.now()-start)
})

// await的时候如果是reject而没有后续处理错误回报错显示未捕获的错误  
// 1.则需要trycatch去执行 否则不执行后续代码
// 2.则需要promise的catch去接受处理错误 否则不执行后续代码
async function async1 () {
  // await Promise.reject('error')

  // try {
  //   await Promise.reject('error')
  // } catch (error) {
  //   console.log('try catch error', error)
  // }

  await Promise.reject('error').catch(err=>{console.log('promise catch',err)})
  console.log('1111111111')
  return Promise.resolve('success')
}

async1().then(res=>console.log('res===',res))
console.log('start')